package com.management1.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.management1.entity.SysPermission;
import com.management1.entity.SysRolePermission;
import com.management1.mapper.SysPermissionMapper;
import com.management1.service.SysPermissionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.management1.service.SysRolePermissionService;
import com.management1.service.SysUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author chenmo
 * @since 2021-04-26
 */
@Service
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    @Resource
    private SysRolePermissionService rolePermissionService;

    //获取全部菜单
    @Override
    public List<SysPermission> queryAllMenu() {
        QueryWrapper<SysPermission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<SysPermission> permissionList = baseMapper.selectList(wrapper);

        return buildMenu(permissionList);
    }

    //根据角色获取菜单
    @Override
    public List<SysPermission> selectAllMenu(Integer roleId) {
        QueryWrapper<SysPermission> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id");
        List<SysPermission> permissionList = baseMapper.selectList(wrapper);
        return buildMenu(permissionList);
    }

    /**
     * 使用递归方法建菜单
     *
     * @param treeNodes
     * @return
     */
    private static List<SysPermission> buildMenu(List<SysPermission> treeNodes) {
        List<SysPermission> trees = new ArrayList<>();
        for (SysPermission treeNode : treeNodes) {
            if (0 == (treeNode.getPid())) {
                treeNode.setLevel(1);
                trees.add(findChildren(treeNode, treeNodes));
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     *
     * @param treeNodes
     * @return
     */
    private static SysPermission findChildren(SysPermission treeNode, List<SysPermission> treeNodes) {
        treeNode.setChildren(new ArrayList<>());

        for (SysPermission it : treeNodes) {
            if (treeNode.getId().equals(it.getPid())) {
                int level = treeNode.getLevel() + 1;
                it.setLevel(level);
                if (treeNode.getChildren() == null) {
                    treeNode.setChildren(new ArrayList<>());
                }
                treeNode.getChildren().add(findChildren(it, treeNodes));
            }
        }
        return treeNode;
    }

    //给角色分配权限
    @Override
    public void saveRolePermissionRelationShip(Integer roleId, Integer[] permissionIds) {
        rolePermissionService.remove(new QueryWrapper<SysRolePermission>().eq("roleId", roleId));

        List<SysRolePermission> rolePermissionList = new ArrayList<>();
        for(Integer permissionId : permissionIds) {
            if(StringUtils.isEmpty(permissionId)) continue;

            SysRolePermission rolePermission = new SysRolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissionList.add(rolePermission);
        }
        rolePermissionService.saveBatch(rolePermissionList);
    }

    //递归删除菜单
    @Override
    public void removeChildById(Integer id) {
        List<Integer> idList = new ArrayList<>();
        this.selectChildListById(id, idList);

        idList.add(id);
        baseMapper.deleteBatchIds(idList);
    }

    //递归获取子节点
    private void selectChildListById(Integer id, List<Integer> idList) {
        List<SysPermission> childList = baseMapper.selectList(new QueryWrapper<SysPermission>().eq("pid", id).select("id"));
        childList.forEach(item -> {
            idList.add(item.getId());
            this.selectChildListById(item.getId(), idList);
        });
    }

    //根据用户id获取用户菜单
    @Override
    public List<String> selectPermissionValueByUserId(Integer id) {
        List<String> selectPermissionValueList = null;
        selectPermissionValueList = baseMapper.selectPermissionValueByUserId(id);
        return selectPermissionValueList;
    }

    @Override
    public List<JSONObject> selectPermissionByUserId(Integer userId) {
        List<SysPermission> selectPermissionList = null;
        selectPermissionList = baseMapper.selectPermissionByUserId(userId);

        List<SysPermission> permissionList = buildMenu(selectPermissionList);
        return buildJSONOMenu(permissionList);
    }

    //构建JSONObject类型的菜单，最多两级
    public static List<JSONObject> buildJSONOMenu(List<SysPermission> treeNodes) {
        List<JSONObject> menus = new ArrayList<>();
        if(treeNodes.size() == 1) {
            SysPermission topNode = treeNodes.get(0);
            //左侧一级菜单
            List<SysPermission> oneMenuList = topNode.getChildren();
            for(SysPermission one :oneMenuList) {
                JSONObject oneMenu = new JSONObject();
                oneMenu.put("path", one.getPath());
                oneMenu.put("component", one.getComponent());
                oneMenu.put("redirect", "noredirect");
                oneMenu.put("name", "name_"+one.getId());
                oneMenu.put("hidden", one.getHidden()== 0);

                JSONObject oneMeta = new JSONObject();
                oneMeta.put("title", one.getName());
                oneMeta.put("icon", one.getIcon());
                oneMenu.put("meta", oneMeta);

                List<JSONObject> children = new ArrayList<>();
                List<SysPermission> twoMenuList = one.getChildren();
                for(SysPermission two :twoMenuList) {
                    JSONObject twoMenu = new JSONObject();
                    twoMenu.put("path", two.getPath());
                    twoMenu.put("component", two.getComponent());
                    twoMenu.put("name", "name_"+two.getId());
                    twoMenu.put("hidden", two.getHidden()== 0);

                    JSONObject twoMeta = new JSONObject();
                    twoMeta.put("title", two.getName());
                    twoMeta.put("icon",two.getIcon());
                    twoMenu.put("meta", twoMeta);

                    children.add(twoMenu);

                    List<SysPermission> threeMeunList = two.getChildren();
                    for(SysPermission three :threeMeunList) {
                        if(StringUtils.isEmpty(three.getPath())) continue;

                        JSONObject threeMeun = new JSONObject();
                        threeMeun.put("path", three.getPath());
                        threeMeun.put("component", three.getComponent());
                        threeMeun.put("name", "name_"+three.getId());
                        threeMeun.put("hidden", three.getHidden() == 0);

                        JSONObject threeMeta = new JSONObject();
                        threeMeta.put("title", three.getName());
                        threeMeta.put("icon",three.getIcon());
                        threeMeun.put("meta", threeMeta);

                        children.add(threeMeun);
                    }
                }
                oneMenu.put("children", children);
                menus.add(oneMenu);
            }
        }
        return menus;
    }
}
